package com.sihan.framework.etm.common.util;


/**
 * 地图坐标距离计算
 *
 */
public class LocationUtils {


    private static final double EARTH_RADIUS_KM = 6378.137;
    private static final double EARTH_RADIUS_MILES = 3958.8;
    private static final double METERS_PER_KM = 1000.0;
    private static final double FEET_PER_MILE = 5280.0;

    private static final double CM_PER_KM = 100000.0;

    private static double rad(double d) {
        return d * Math.PI / 180.0;
    }

    /**
     * 经过经纬度获取距离(单位：米)
     * @param lng1 经度1
     * @param lat1 纬度1
     * @param lng2 经度2
     * @param lat2 纬度2
     * @return
     */
    public static double getDistance(double lng1, double lat1, double lng2,
                                     double lat2) {
        double radLat1 = rad(lat1);
        double radLat2 = rad(lat2);
        double a = radLat1 - radLat2;
        double b = rad(lng1) - rad(lng2);
        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2)
                + Math.cos(radLat1) * Math.cos(radLat2)
                * Math.pow(Math.sin(b / 2), 2)));
        s = s * EARTH_RADIUS_KM;
        s = Math.round(s * 10000d) / 10000d;
        s = s*1000;
        return s;
    }


    /**
     * 经过经纬度获取距离
     *
     * @param lng1   经度1
     * @param lat1   纬度1
     * @param lng2   经度2
     * @param lat2   纬度2
     * @param unit   单位（km, miles, meters, feet, cm）
     * @return 距离值 km千米 miles 英里 meters 米 feet 尺 cm 厘米
     */
    public static double getDistance(double lng1, double lat1, double lng2, double lat2, String unit) {
        double radLat1 = rad(lat1);
        double radLat2 = rad(lat2);
        double a = radLat1 - radLat2;
        double b = rad(lng1) - rad(lng2);
        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2)
                + Math.cos(radLat1) * Math.cos(radLat2)
                * Math.pow(Math.sin(b / 2), 2)));
        s = s * EARTH_RADIUS_KM;

        if ("km".equals(unit)) {
            return s;
        } else if ("miles".equals(unit)) {
            s = s * EARTH_RADIUS_MILES / EARTH_RADIUS_KM;
        } else if ("meters".equals(unit)) {
            s = s * METERS_PER_KM;
        } else if ("feet".equals(unit)) {
            s = s * EARTH_RADIUS_MILES * FEET_PER_MILE / EARTH_RADIUS_KM;
        }else if ("cm".equals(unit)) {
            s = s * CM_PER_KM;
        } else {
            throw new IllegalArgumentException("Invalid unit: " + unit);
        }

        return s;
    }



    /**
     * 判断坐标与标点位置是否出现偏移 偏移值是否大于 规定指定值
     *
     * @param lng
     * @param let
     * @param lng1
     * @param let1
     * @param distance 规定偏移值
     * @return 未超出指定值 返回true 反为false
     */
    public static Boolean OffsetOrNot(double lng,double let,double lng1,double let1,double distance){
        double distance1 = LocationUtils.getDistance(lng, let, lng1, let1,"meters");
        System.out.println("=========="+lng+","+let+"--"+lng1+","+let1+"差值:"+distance1);
        return distance1 <= distance;
    }


    /**
     * 将度分格式转换为度分秒格式
     * @param latOrLon 经度或纬度的度分格式字符串，如：120°10.5'
     * @return 度分秒格式的字符串，如：120°10'30"
     */
    public static String convertDegreeMinuteToDegreeSecond(String latOrLon) {
        double degree = Double.parseDouble(latOrLon.substring(0, latOrLon.indexOf("°")));
        double minute = Double.parseDouble(latOrLon.substring(latOrLon.indexOf("°") + 1, latOrLon.indexOf("'")));
        double second = (Double.parseDouble(latOrLon.substring(latOrLon.indexOf("'") + 1, latOrLon.length() - 1)) * 60) / 1000;
        return String.format("%s°%s'%s\"", degree, minute, second);
    }

    /**
     * 将度分秒格式转换为度分格式
     * @param latOrLon 经度或纬度的度分秒格式字符串，如：120°10'30"
     * @return 度分格式的字符串，如：120°10.5'
     */
    public static String convertDegreeSecondToDegreeMinute(String latOrLon) {
        double degree = Double.parseDouble(latOrLon.substring(0, latOrLon.indexOf("°")));
        double minute = Double.parseDouble(latOrLon.substring(latOrLon.indexOf("°") + 1, latOrLon.indexOf("'")));
        double second = Double.parseDouble(latOrLon.substring(latOrLon.indexOf("'") + 1, latOrLon.indexOf("\"")));
        double minuteDecimal = minute + (second / 60);
        return String.format("%s°%.6f'", degree, minuteDecimal);
    }
    /**
     * 
     *
     * @author 苏伟洪
     * @param degree
     *
     * @date 2023/04/26 16:04:56
     *
     * @return double
     */
    public static double convertToDecimal(String degree) {
        String[] degreeArr = degree.split("[°'\"']");
        double d = Double.parseDouble(degreeArr[0]);
        double m = Double.parseDouble(degreeArr[1]);
        double s = Double.parseDouble(degreeArr[2]);
        double decimalDegree = d + m / 60 + s / 3600;
        decimalDegree = Double.parseDouble(String.format("%.10f", decimalDegree));
        // 根据坐标所在的纬度或经度，确定其符号
        if (degree.endsWith("N") || degree.endsWith("E")) {
            return decimalDegree;
        } else if (degree.endsWith("S") || degree.endsWith("W")) {
            return -decimalDegree;
        } else {
            throw new IllegalArgumentException("Invalid degree format: " + degree);
        }
    }

    public static void main(String[] args) {
        String degree = "30°27'36.4368\"N";
        double decimalDegree = convertToDecimal(degree);

        String degree1 = "104°00'58.3410\"E";
        double decimalDegree1 = convertToDecimal(degree1);
        System.out.println(decimalDegree+","+decimalDegree1);

        String degree2 = "30°27'36.4972\"N";
        double decimalDegree2 = convertToDecimal(degree2);
        String degree3 = "104°00'58.3530\"E";
        double decimalDegree3 = convertToDecimal(degree3);
        System.out.println(decimalDegree2+","+decimalDegree3);
    }


//    public static void main(String[] args) {
//        String lat = "30°27'364337";
//        lat = convertDegreeMinuteToDegreeSecond(lat);
//        String lng = "104°00'583157";
//        lng = convertDegreeMinuteToDegreeSecond(lng);
//        System.out.println(lat+lng);
//        //OffsetOrNot(Long.parseLong(lat),Long.parseLong(lng),30.460122,104.016196,6);
//        OffsetOrNot(30.27364337,104.00583157,30.460122,104.016196,6);
//
//    }
//
//    public static void main(String[] args) {
//        // 创建WGS84椭球体
//        Ellipsoid earth = Ellipsoid.WGS84;
//
//        // 创建两个坐标点对象
//        GlobalPosition pointA = new GlobalPosition(30.27364337, 104.00583157, 0.0);
//        GlobalPosition pointB = new GlobalPosition(30.460122, 104.016196, 0.0);
//
//        // 计算两个坐标点之间的距离（单位为米）
//        GeodeticCalculator calculator = new GeodeticCalculator();
//        double distance = calculator.calculateGeodeticCurve(earth, pointA, pointB).getEllipsoidalDistance();
//        System.out.println(distance);
//    }

}
